package com.bsj.sipgateway.web.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.bsj.power.common.config.exception.ApiException;
import com.bsj.power.common.config.global.JsonResult;
import com.bsj.power.common.config.global.JsonResultEnum;
import com.bsj.power.common.config.redis.RedisConstant;
import com.bsj.power.common.def.dto.RedisDeviceInfo;
import com.bsj.power.common.def.dto.SceneDTO;
import com.bsj.power.common.def.entity.Scene;
import com.bsj.power.common.def.entity.alarmReport.AlarmReport;
import com.bsj.power.common.def.entity.gb28181.Device;
import com.bsj.power.common.def.entity.gb28181.DeviceChannel;
import com.bsj.power.common.def.entity.job.Job;
import com.bsj.power.common.def.entity.path.Path;
import com.bsj.power.common.def.vo.*;
import com.bsj.power.common.mapper.*;
import com.bsj.power.common.util.DateUtils;
import com.bsj.sipgateway.common.constant.Constants;
import com.bsj.sipgateway.util.RedisDeviceInfoUtil;
import com.bsj.sipgateway.web.service.IDeviceService;
import com.bsj.sipgateway.web.service.ISceneService;
import com.github.pagehelper.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import redis.clients.bsj.JedisClusterBSJ;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description 场景管理
 * @Author zhaoyang
 * @menu 场景管理
 * @Date 2024/5/11 10:53
 */
@Slf4j
@RestController
@RequestMapping("/api/scene")
//@SaCheckPermission("/video/api/scene")
public class SceneController {

    @Autowired
    @Qualifier("sceneServiceImpl")
    private ISceneService sceneService;

    @Autowired
    @Qualifier("deviceServiceImpl")
    private IDeviceService deviceService;

    @Autowired
    private JedisClusterBSJ jedisClusterBSJ;

    @Autowired
    private RedisDeviceInfoUtil redisDeviceInfoUtil;

    @Resource
    private JobMapper jobMapper;

    @Resource
    private JobPersonnelMapper jobPersonnelMapper;

    @Resource
    private AlarmReportMapper alarmReportMapper;

    @Autowired
    private AttentionMapper attentionMapper;

    @Autowired
    private AttentionDeviceMapper attentionDeviceMapper;

    @Autowired
    private PathMapper pathMapper;

    @Autowired
    private DeviceChannelMapper deviceChannelMapper;

    /**
     * 添加场景信息
     *
     * @param sceneDTO
     * @return: com.bsj.power.common.config.global.JsonResult
     * @decription
     * @author zhaoyang
     * @date 2024/5/11 14:38
     */
    @PostMapping("/add")
    public JsonResult add(@RequestBody SceneDTO sceneDTO) {
        if (sceneDTO == null || StringUtil.isEmpty(sceneDTO.getSceneName())) {
            throw new ApiException(JsonResultEnum.PARAM_ERROR);
        }

        JsonResult result = new JsonResult();
        // 不做场景重名的限制
//        boolean exists = sceneService.existsByName(sceneDTO.getSceneName());
//        if (exists) {
//            result.setCode(-1);
//            result.setMsg("场景名称已经存在，请重新输入");
//            return result;
//        }
        Scene scene = new Scene();
        BeanUtils.copyProperties(sceneDTO, scene);

        Scene savedScene = sceneService.add(scene);
        if (savedScene == null) {
            result.setCode(-1);
            result.setMsg("新增失败");
            return result;
        }
        result.setCode(JsonResultEnum.SUCCESS.getCode());
        result.setMsg(JsonResultEnum.SUCCESS.getMsg());
        result.setData(sceneDTO);
        return result;
    }

    /**
     * 修改场景信息
     *
     * @param sceneDTO
     * @return: com.bsj.power.common.config.global.JsonResult
     * @decription
     * @author zhaoyang
     * @date 2024/5/11 15:39
     */
    @PostMapping("/update")
    public JsonResult update(@RequestBody SceneDTO sceneDTO) {
        if (sceneDTO == null || StringUtil.isEmpty(sceneDTO.getSceneName())) {
            throw new ApiException(JsonResultEnum.PARAM_ERROR);
        }
//        if (sceneDTO.getPid() == -1) {
//            JsonResult jsonResult = new JsonResult();
//            jsonResult.setCode(-1);
//            jsonResult.setMsg("最上级场景不支持修改，请联系管理员进行操作");
//            return jsonResult;
//        }
//        // 如果旧的场景名称关联了作业区域，名称修改其他的修改并给出名称未修改的提示
//        Scene byId = sceneService.findById(sceneDTO.getId());
//        List<Job> jobs = jobMapper.selectByWorkArea(byId.getSceneName());
//        if (!CollectionUtils.isEmpty(jobs)) {
//            sceneDTO.setSceneName(byId.getSceneName());
//        }
        Scene scene = new Scene();
        BeanUtils.copyProperties(sceneDTO, scene);

        boolean flag = sceneService.update(scene);
        if (flag) {
//            if (!CollectionUtils.isEmpty(jobs)) {
//                JsonResult jsonResult = new JsonResult();
//                jsonResult.setCode(JsonResultEnum.SUCCESS.getCode());
//                jsonResult.setMsg("修改成功");
//                return jsonResult;
//            } else {
            return JsonResult.success();
//            }
        }
        return JsonResult.fail();
    }

    /**
     * 根据id查询场景信息
     *
     * @param sceneId
     * @return: com.bsj.power.common.config.global.JsonResult
     * @decription
     * @author zhaoyang
     * @date 2024/5/11 16:31
     */
    @RequestMapping("/findById")
    public JsonResult findById(@RequestParam Integer sceneId) {
        if (sceneId == null) {
            throw new ApiException(JsonResultEnum.PARAM_ERROR);
        }
        Scene scene = sceneService.findById(sceneId);
        JsonResult result;
        if (scene != null) {
            result = JsonResult.success();
            result.setData(scene);
        } else {
            result = JsonResult.fail();
            result.setMsg("没有查询到相关场景信息");
        }
        return result;
    }

    /**
     * 根据id删除场景
     *
     * @param sceneId
     * @return: com.bsj.power.common.config.global.JsonResult
     * @decription 根据id删除场景
     * @author zhaoyang
     * @date 2024/5/13 14:47
     */
    @GetMapping("/deleteById")
    public JsonResult deleteById(Integer sceneId) {
        if (sceneId == null) {
            return JsonResult.paramError();
        }
//        if (sceneId == 1) {
//            JsonResult jsonResult = new JsonResult();
//            jsonResult.setCode(-1);
//            jsonResult.setMsg("最上级场景不支持删除，请联系管理员进行操作");
//            return jsonResult;
//        }
        // 如果场景下有摄像头，不删除给提示
        List<Device> devices = deviceService.selectBySceneId(sceneId);
        if (!CollectionUtils.isEmpty(devices)) {
            JsonResult jsonResult = new JsonResult();
            jsonResult.setCode(-1);
            jsonResult.setMsg("当前场景存在摄像头无法直接删除");
            return jsonResult;
        }
//        // 如果有场景名称关联工单的作业区域，也不能删除，给提示
//        Scene byId = sceneService.findById(sceneId);
//        List<Job> jobs = jobMapper.selectByWorkArea(byId.getSceneName());
//        if (!CollectionUtils.isEmpty(jobs)) {
//            JsonResult jsonResult = new JsonResult();
//            jsonResult.setCode(-1);
//            jsonResult.setMsg("当前场景关联了作业工单无法直接删除");
//            return jsonResult;
//        }

        List<Integer> childSceneIds = sceneService.selectSceneIdByPid(sceneId);
        if (childSceneIds.size() != 0) {
            JsonResult jsonResult = new JsonResult();
            jsonResult.setCode(-1);
            jsonResult.setMsg("当前场景存在下级无法直接删除");
            return jsonResult;
        }

        sceneService.deleteScene(sceneId);
        return JsonResult.success();

    }

    /**
     * 绑定视频设备
     *
     * @param sceneId 场景id
     * @param dids    国标设备数据库id
     * @return: com.bsj.power.common.config.global.JsonResult
     * @decription 绑定视频设备
     * @author zhaoyang
     * @date 2024/5/13 11:41
     */
    @GetMapping("/bindVideoDevice")
    public JsonResult bindVideoDevices(Integer sceneId, Long[] dids) {
        if (sceneId == null || dids.length == 0) {
            return JsonResult.paramError();
        }
        sceneService.updateSceneIdByIds(sceneId, dids);
        return JsonResult.success();
    }


    /**
     * 解除绑定
     *
     * @param sceneId 场景id
     * @param did     国标设备数据库id
     * @return: com.bsj.power.common.config.global.JsonResult
     * @decription
     * @author zhaoyang
     * @date 2024/5/13 11:44
     */
    @GetMapping("/unbindVideoDevice")
    public JsonResult unbindVideoDevice(Integer sceneId, Long did) {
        if (sceneId == null || did == null) {
            return JsonResult.paramError();
        }
        sceneService.unbindVideoDevice(sceneId, did);
        return JsonResult.success();
    }

    /**
     * 查询场景下绑定的设备
     *
     * @param sceneId
     * @return: com.bsj.power.common.config.global.JsonResult
     * @decription 查询场景下绑定的设备
     * @author zhaoyang
     * @date 2024/5/13 15:23
     */
    @GetMapping("/listVideoDevicesBySceneId")
    public JsonResult listVideoDevicesBySceneId(Integer sceneId) {
        List<Device> devices = null;
        if (sceneId == null) {
            devices = deviceService.findAll();
        } else {
            devices = sceneService.listVideoDevicesBySceneId(sceneId);
        }
        devices.removeIf(device -> StringUtil.isEmpty(device.getPointJson()));

        List<String> deviceIds = devices.stream().map(Device::getDeviceId).collect(Collectors.toList());
        Map<String, List<DeviceChannel>> deviceChannelMap = null;
        if (!CollectionUtils.isEmpty(deviceIds)) {
            List<DeviceChannel> deviceChannels = deviceChannelMapper.queryAllByDeviceIds(deviceIds);
            deviceChannelMap = deviceChannels.stream().collect(Collectors.groupingBy(DeviceChannel::getDeviceId));
        }


        Map<String, List<DeviceChannel>> finalDeviceChannelMap = deviceChannelMap;
        devices.forEach(device -> {
            String rdsInfo = jedisClusterBSJ.get(RedisConstant.REDIS_DEVICE_INFO + device.getDeviceId());
            if (!StringUtil.isEmpty(rdsInfo)) {
                RedisDeviceInfo redisDeviceInfo = JSON.parseObject(rdsInfo, RedisDeviceInfo.class);
                device.setOnline(redisDeviceInfo.getOnline());
            } else {
                device.setOnline(Constants.DEVICE_OFFLINE);
            }

            String channelIdStr = device.getChannelIdStr();
            if (!StringUtils.isEmpty(channelIdStr)) {
                if (finalDeviceChannelMap != null) {
                    List<DeviceChannel> deviceChannelList = finalDeviceChannelMap.get(device.getDeviceId());
                    device.setDeviceChannels(deviceChannelList);
                }
            }

            String lockedStr = redisDeviceInfoUtil.getPtzControlLock(device.getDeviceId());
            if (!StringUtil.isEmpty(lockedStr) && !"null".equals(lockedStr)) {
                String[] s = lockedStr.split("_");
                if (s.length == 2) {
                    device.setPtzControlLock(1);
                    device.setLockUid(Integer.parseInt(s[0]));
                    device.setLockedUserWeight(Integer.parseInt(s[1]));
                }
            } else {
                device.setPtzControlLock(0);
            }

        });

        JsonResult result = JsonResult.success();
        result.setData(devices);
        result.setTotal(devices.size());
        return result;

    }


    /**
     * 根据场景名称查询对应的视频设备
     *
     * @param sceneName
     * @return
     */
    @GetMapping("/listDevicesBySceneName")
    public JsonResult listDevicesBySceneName(@RequestParam String sceneName) {
        if (StringUtil.isEmpty(sceneName)) {
            throw new ApiException(JsonResultEnum.PARAM_ERROR);
        }
        Scene scene = sceneService.findBySceneName(sceneName);
        JsonResult jsonResult = new JsonResult();
        if (scene == null) {
            jsonResult.setCode(-1);
            jsonResult.setMsg("没有这个场景");
            return jsonResult;
        }
        List<Device> devices = sceneService.listVideoDevicesBySceneId(scene.getId());
        if (CollectionUtils.isEmpty(devices)) {
            jsonResult.setCode(-1);
            jsonResult.setMsg("该场景下没有视频设备");
            return jsonResult;
        }
        List<DeviceVO> deviceVOS = new ArrayList<>();
        devices.stream().forEach(device -> {
            DeviceVO deviceVO = new DeviceVO();
            BeanUtils.copyProperties(device, deviceVO);
            String lockedStr = redisDeviceInfoUtil.getPtzControlLock(deviceVO.getDeviceId());
            if (!StringUtil.isEmpty(lockedStr)) {
                String[] s = lockedStr.split("_");
                deviceVO.setPtzControlLock(1);
                deviceVO.setLockedUserWeight(Integer.parseInt(s[1]));
            } else {
                deviceVO.setPtzControlLock(0);
            }
            String rdsInfo = jedisClusterBSJ.get(RedisConstant.REDIS_DEVICE_INFO + deviceVO.getDeviceId());
            if (!StringUtil.isEmpty(rdsInfo)) {
                RedisDeviceInfo redisDeviceInfo = JSON.parseObject(rdsInfo, RedisDeviceInfo.class);
                deviceVO.setOnline(redisDeviceInfo.getOnline());
                deviceVO.setFault(redisDeviceInfo.getFault());
            }
            deviceVOS.add(deviceVO);
        });
        jsonResult.setCode(JsonResultEnum.SUCCESS.getCode());
        jsonResult.setMsg(JsonResultEnum.SUCCESS.getMsg());
        jsonResult.setData(deviceVOS);
        return jsonResult;
    }


    /**
     * @param page
     * @param size
     * @return: com.bsj.power.common.config.global.JsonResult<java.util.List < com.bsj.power.common.def.entity.Scene>>
     * @decription 分页查询场景信息（没关联设备）
     * @author zhaoyang
     * @date 2024/5/29 15:34
     */
    @RequestMapping("/pageQuerySceneList")
    public JsonResult<List<Scene>> pageQuerySceneList(@RequestParam Integer page, @RequestParam Integer size
            , @RequestParam(required = false) Integer isSensitived) {
        JsonResult<List<Scene>> result;
        if (page == null || size == null) {
            page = 1;
            size = 10;
        }
        IPage<Scene> iPage = sceneService.pageQuerySceneList(page, size, isSensitived);
        if (iPage != null && !CollectionUtils.isEmpty(iPage.getRecords())) {
            result = JsonResult.success(JsonResultEnum.SUCCESS);
            result.setTotal((int) iPage.getTotal());
            result.setData(iPage.getRecords());
        } else {
            result = new JsonResult<>();
            result.setCode(0);
            result.setMsg("暂无数据");
        }
        return result;
    }


    /**
     * @param page
     * @param size
     * @return: com.bsj.power.common.config.global.JsonResult<java.util.List < com.bsj.power.common.def.vo.SceneDeviceVO>>
     * @decription 分页查询场景信息关联设备
     * @author zhaoyang
     * @date 2024/5/29 19:50
     */
    @RequestMapping("/pageQuerySceneDeviceList")
    public JsonResult<List<SceneDeviceVO>> pageQuerySceneDeviceList(@RequestParam Integer page, @RequestParam Integer size) {
        if (page == null || size == null) {
            page = 1;
            size = 10;
        }
        JsonResult result = new JsonResult();
        IPage<Scene> iPage = sceneService.pageQuerySceneList(page, size, null);
        List<Scene> records = iPage.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            result.setCode(0);
            result.setMsg("没有查询到场景信息");
            return result;
        }
        // 返回结果集
        List<SceneDeviceVO> resultList = new ArrayList<>();
        List<Integer> sceneIds = records.stream().map(Scene::getId).collect(Collectors.toList());
        List<Device> devices = deviceService.selectBySceneIds(sceneIds);

        List<String> deviceIds = devices.stream().map(Device::getDeviceId).collect(Collectors.toList());
        List<DeviceChannel> deviceChannels = deviceChannelMapper.queryAllByDeviceIds(deviceIds);
        Map<String, List<DeviceChannel>> deviceChannelMap = deviceChannels.stream().collect(Collectors.groupingBy(DeviceChannel::getDeviceId));

        List<DeviceVO> deviceVOS = new ArrayList<>();

        result.setCode(200);
        result.setMsg("请求成功");
        if (CollectionUtils.isEmpty(devices)) {
            for (Scene scene : records) {
                SceneDeviceVO vo = new SceneDeviceVO();
                vo.setId(scene.getId());
                vo.setPid(scene.getPid());
                vo.setSceneName(scene.getSceneName());
                vo.setRemark(scene.getRemark());
                vo.setFloor(scene.getFloor());
                vo.setBuilding(scene.getBuilding());
                vo.setSerialNum(scene.getSerialNum());
                resultList.add(vo);
            }
        } else {
            for (Device device : devices) {
                DeviceVO deviceVO = new DeviceVO();
                BeanUtils.copyProperties(device, deviceVO);
                String channelIdStr = device.getChannelIdStr();
                if (!StringUtils.isEmpty(channelIdStr)) {
                    List<DeviceChannel> deviceChannelList = deviceChannelMap.get(device.getDeviceId());
                    deviceVO.setDeviceChannels(deviceChannelList);
                }

                String lockedStr = redisDeviceInfoUtil.getPtzControlLock(deviceVO.getDeviceId());
                if (!StringUtil.isEmpty(lockedStr) && !"null".equals(lockedStr)) {
                    String[] s = lockedStr.split("_");
                    if (s.length == 2) {
                        deviceVO.setPtzControlLock(1);
                        deviceVO.setLockUid(Integer.parseInt(s[0]));
                        deviceVO.setLockedUserWeight(Integer.parseInt(s[1]));
                    }
                } else {
                    deviceVO.setPtzControlLock(0);
                }
                RedisDeviceInfo redisDeviceInfo = redisDeviceInfoUtil.getRedisDeviceInfo(device.getDeviceId());
                if (redisDeviceInfo == null) {
                    deviceVO.setOnline(Constants.DEVICE_OFFLINE);
                } else {
                    deviceVO.setFault(redisDeviceInfo.getFault());
                    boolean onlineFlag = redisDeviceInfo.getOnline() == Constants.DEVICE_ONLINE
                            && (System.currentTimeMillis() - redisDeviceInfo.getKeepAliveTime()) < 180000L;
                    if (onlineFlag) {
                        deviceVO.setOnline(Constants.DEVICE_ONLINE);
                    } else {
                        deviceVO.setOnline(Constants.DEVICE_OFFLINE);
                    }
                }
                deviceVOS.add(deviceVO);
            }

            Map<Integer, List<DeviceVO>> map = deviceVOS.stream().collect(Collectors.groupingBy(DeviceVO::getSceneId));
            for (Scene scene : records) {
                SceneDeviceVO vo = new SceneDeviceVO();
                vo.setId(scene.getId());
                vo.setPid(scene.getPid());
                vo.setSceneName(scene.getSceneName());
                vo.setRemark(scene.getRemark());
                vo.setFloor(scene.getFloor());
                vo.setBuilding(scene.getBuilding());
                vo.setSerialNum(scene.getSerialNum());
                List<DeviceVO> deviceVOS1 = map.get(scene.getId());
                if (deviceVOS1 == null) { // 场景下没有绑定设备
                    resultList.add(vo);
                    continue;
                }
                long count = deviceVOS1.stream().filter(deviceVO -> deviceVO.getOnline() == Constants.DEVICE_ONLINE).count();
                vo.setTotalCount(deviceVOS1.size());
                vo.setOnlineCount((int) count);
                vo.setOfflineCount((int) (deviceVOS1.size() - count));
                vo.setDeviceList(deviceVOS1);
                resultList.add(vo);
            }
        }
        for (SceneDeviceVO sceneDeviceVO : resultList) {
            List<DeviceVO> deviceList = sceneDeviceVO.getDeviceList();
            if (!CollectionUtils.isEmpty(deviceList)) {
                List<DeviceVO> collect = deviceList.stream().sorted(Comparator.comparing(DeviceVO::getNickName)).collect(Collectors.toList());
                sceneDeviceVO.setDeviceList(collect);
            }
        }

        // 重新组织每个场景下都要有设备数量
        for (SceneDeviceVO sceneDeviceVO : resultList) {
            List<Integer> childIds = sceneService.getSceneIds(sceneDeviceVO.getId(), 2);
            if (!CollectionUtils.isEmpty(childIds)) {
                sceneDeviceVO.setChildIdList(childIds);

                List<DeviceVO> dvos = deviceVOS.stream().filter(deviceVO -> childIds.contains(deviceVO.getSceneId()))
                        .collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(dvos)) {
                    List<DeviceVO> onlineDvos = dvos.stream().filter(deviceVO -> deviceVO.getOnline().equals(Constants.DEVICE_ONLINE)).collect(Collectors.toList());
                    sceneDeviceVO.setTotalCount(dvos.size());
                    sceneDeviceVO.setOnlineCount(onlineDvos.size());
                    sceneDeviceVO.setOfflineCount(dvos.size() - onlineDvos.size());
                }
            }
        }

        List<SceneDeviceVO> collect = resultList.stream().sorted(Comparator.comparing(SceneDeviceVO::getSerialNum)).collect(Collectors.toList());

        result.setData(collect);
        return result;

    }


//    private List<SceneDeviceVO> findChildren(List<SceneDeviceVO> allScenes, int parentId) {
//        List<SceneDeviceVO> children = new ArrayList<>();
//        for (SceneDeviceVO vo : allScenes) {
//            if (vo.getPid() == parentId) {
//                List<SceneDeviceVO> subChildren = findChildren(allScenes, vo.getId());
//                vo.setChild(subChildren);
//                children.add(vo);
//            }
//        }
//        return children;
//    }


    /**
     * @param page
     * @param size
     * @return: com.bsj.power.common.config.global.JsonResult<java.util.List < com.bsj.power.common.def.vo.SceneDeviceVO>>
     * @decription 分页查询场景信息关联设备
     * @author zhaoyang
     * @date 2024/5/29 19:50
     */
    @RequestMapping("/pageQuerySceneDeviceList2")
    public JsonResult<List<SceneDeviceVO>> pageQuerySceneDeviceList2(@RequestParam Integer page, @RequestParam Integer size) {
        if (page == null || size == null) {
            page = 1;
            size = 10;
        }
        JsonResult result = new JsonResult();
        IPage<Scene> iPage = sceneService.pageQuerySceneList(page, size, null);
        List<Scene> records = iPage.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            result.setCode(0);
            result.setMsg("没有查询到场景信息");
            return result;
        }
        // 返回结果集
        List<SceneDeviceVO> resultList = new ArrayList<>();
        List<Integer> sceneIds = records.stream().map(Scene::getId).collect(Collectors.toList());
        List<Device> devices = deviceService.selectBySceneIds(sceneIds);

        result.setCode(200);
        result.setMsg("请求成功");
        if (CollectionUtils.isEmpty(devices)) {
            for (Scene scene : records) {
                SceneDeviceVO vo = new SceneDeviceVO();
                vo.setId(scene.getId());
                vo.setPid(scene.getPid());
                vo.setSceneName(scene.getSceneName());
                vo.setRemark(scene.getRemark());
                resultList.add(vo);
            }
        } else {
            List<DeviceVO> deviceVOS = new ArrayList<>();
            devices.stream().forEach(device -> {
                DeviceVO deviceVO = new DeviceVO();
                BeanUtils.copyProperties(device, deviceVO);
                String lockedStr = redisDeviceInfoUtil.getPtzControlLock(deviceVO.getDeviceId());
                if (!StringUtil.isEmpty(lockedStr) && !"null".equals(lockedStr)) {
                    String[] s = lockedStr.split("_");
                    deviceVO.setPtzControlLock(1);
                    deviceVO.setLockUid(Integer.parseInt(s[0]));
                    deviceVO.setLockedUserWeight(Integer.parseInt(s[1]));
                } else {
                    deviceVO.setPtzControlLock(0);
                }
                String rdsInfo = jedisClusterBSJ.get(RedisConstant.REDIS_DEVICE_INFO + deviceVO.getDeviceId());
                if (!StringUtil.isEmpty(rdsInfo)) {
                    RedisDeviceInfo redisDeviceInfo = JSON.parseObject(rdsInfo, RedisDeviceInfo.class);
                    deviceVO.setOnline(redisDeviceInfo.getOnline());
                    deviceVO.setFault(redisDeviceInfo.getFault());
                } else {
                    deviceVO.setOnline(Constants.DEVICE_OFFLINE);
                }
                deviceVOS.add(deviceVO);
            });

            Map<Integer, List<DeviceVO>> map = deviceVOS.stream().collect(Collectors.groupingBy(DeviceVO::getSceneId));
            for (Scene scene : records) {
                SceneDeviceVO vo = new SceneDeviceVO();
                vo.setId(scene.getId());
                vo.setPid(scene.getPid());
                vo.setSceneName(scene.getSceneName());
                vo.setRemark(scene.getRemark());
                List<DeviceVO> deviceVOS1 = map.get(scene.getId());
                if (deviceVOS1 == null) { // 场景下没有绑定设备
                    resultList.add(vo);
                    continue;
                }
                long count = deviceVOS1.stream().filter(deviceVO -> deviceVO.getOnline() == Constants.DEVICE_ONLINE).count();
                vo.setTotalCount(deviceVOS1.size());
                vo.setOnlineCount((int) count);
                vo.setOfflineCount((int) (deviceVOS1.size() - count));
                vo.setDeviceList(deviceVOS1);
                resultList.add(vo);
            }
        }
        for (SceneDeviceVO sceneDeviceVO : resultList) {
            List<DeviceVO> deviceList = sceneDeviceVO.getDeviceList();
            if (!CollectionUtils.isEmpty(deviceList)) {
                List<DeviceVO> collect = deviceList.stream().sorted(Comparator.comparing(DeviceVO::getNickName)).collect(Collectors.toList());
                sceneDeviceVO.setDeviceList(collect);
            }
        }

        List<SceneDeviceVO> sceneDeviceVOS = buildTree2(-1, resultList);

        result.setData(sceneDeviceVOS);
        result.setTotal(iPage.getTotal());
        return result;

    }

    private static List<SceneDeviceVO> buildTree2(int parentId, List<SceneDeviceVO> nodes) {
        List<SceneDeviceVO> rootNodes = new ArrayList<>();
        for (SceneDeviceVO node : nodes) {
            if (node.getPid() == parentId) {
                List<SceneDeviceVO> child = buildTree2(node.getId(), nodes);
                node.setChild(child);
                rootNodes.add(node);
            }
        }
        return rootNodes;
    }


    /**
     * @param
     * @return: com.bsj.power.common.config.global.JsonResult
     * @decription 根据场景名称模糊搜索场景信息
     * @author zhaoyang
     * @date 2024/6/28 16:54
     */
    @RequestMapping("/vagueSearchForSceneName")
    public JsonResult vagueSearchForSceneName(@RequestParam("sceneName") String sceneName) {
        if (sceneName == null) {
            throw new ApiException(JsonResultEnum.PARAM_ERROR);
        }
        List<Scene> scenes = sceneService.vagueSearchForSceneName(sceneName);
        JsonResult jsonResult = new JsonResult();
        if (CollectionUtils.isEmpty(scenes)) {
            jsonResult.setCode(0);
            jsonResult.setMsg("暂无数据");
        }
        // 最上级不能绑定设备，去掉
//        scenes.removeIf(scene -> scene.getPid() == 1);
        jsonResult.setCode(JsonResultEnum.SUCCESS.getCode());
        jsonResult.setMsg(JsonResultEnum.SUCCESS.getMsg());
        jsonResult.setData(scenes);
        jsonResult.setTotal(scenes.size());
        return jsonResult;
    }


    /**
     * @param
     * @return: com.bsj.power.common.config.global.JsonResult
     * @decription 查询所有的场景信息
     * @author zhaoyang
     * @date 2024/6/28 16:54
     */
    @RequestMapping("/findAllScene")
    public JsonResult findAllScene() {
        List<Scene> scenes = sceneService.findAllScene();
        JsonResult jsonResult = new JsonResult();
        if (CollectionUtils.isEmpty(scenes)) {
            jsonResult.setCode(0);
            jsonResult.setMsg("暂无数据");
        }
        jsonResult.setCode(JsonResultEnum.SUCCESS.getCode());
        jsonResult.setMsg(JsonResultEnum.SUCCESS.getMsg());
        jsonResult.setData(scenes);
        jsonResult.setTotal(scenes.size());
        return jsonResult;
    }


    /**
     * @param
     * @return: com.bsj.power.common.config.global.JsonResult
     * @decription 查询所有的场景信息并分级显示
     * @author zhaoyang
     * @date 2024/6/28 16:54
     */
    @RequestMapping("/findAllSceneByLevel")
    public JsonResult findAllSceneByLevel() {
        List<Scene> scenes = sceneService.findAllScene();
        JsonResult jsonResult = new JsonResult();
        if (CollectionUtils.isEmpty(scenes)) {
            jsonResult.setCode(-1);
            jsonResult.setMsg("暂无数据");
        }

        List<SceneLevelVO> nodes = new ArrayList<>();
        scenes.forEach(scene -> {
            SceneLevelVO vo = new SceneLevelVO();
            BeanUtils.copyProperties(scene, vo);
            if (scene.getCreateTime() != null) {
                vo.setCreateTime(DateUtils.dateToStr(scene.getCreateTime()));
            }
            nodes.add(vo);
        });
        List<SceneLevelVO> collect = nodes.stream().sorted(Comparator.comparing(SceneLevelVO::getSerialNum)).collect(Collectors.toList());

        List<SceneLevelVO> sceneLevelVOS = buildTree(-1, collect);

        jsonResult.setCode(JsonResultEnum.SUCCESS.getCode());
        jsonResult.setMsg(JsonResultEnum.SUCCESS.getMsg());
        jsonResult.setData(sceneLevelVOS);
        jsonResult.setTotal(sceneLevelVOS.size());
        return jsonResult;
    }

    private static List<SceneLevelVO> buildTree(int parentId, List<SceneLevelVO> nodes) {
        List<SceneLevelVO> rootNodes = new ArrayList<>();
        for (SceneLevelVO node : nodes) {
            if (node.getPid() == parentId) {
                List<SceneLevelVO> child = buildTree(node.getId(), nodes);
                node.setChild(child);
                rootNodes.add(node);
            }
        }
        return rootNodes;
    }


    /**
     * @param
     * @return: com.bsj.power.common.config.global.JsonResult
     * @decription 查询敏感区域及关联的设备信息
     * @author zhaoyang
     * @date 2024/6/28 16:54
     */
    @RequestMapping("/findSensitiveScene")
    public JsonResult findSensitiveScene() {
        List<Scene> scenes = sceneService.findSensitiveScene();
        JsonResult jsonResult = new JsonResult();
        if (CollectionUtils.isEmpty(scenes)) {
            jsonResult.setCode(0);
            jsonResult.setMsg("暂无数据");
            return jsonResult;
        }

        List<Integer> sceneIds = scenes.stream().mapToInt(Scene::getId).boxed().collect(Collectors.toList());
        List<Device> devices = deviceService.selectBySceneIds(sceneIds);
        Map<Integer, List<Device>> sceneIdDeviceMap;
        if (CollectionUtils.isEmpty(devices)) {
            sceneIdDeviceMap = new HashMap<>();
        } else {
            sceneIdDeviceMap = devices.stream().collect(Collectors.groupingBy(Device::getSceneId));
        }
        List<SensitiveSceneVO> resultVOs = new ArrayList<>();
        scenes.forEach(scene -> {
            SensitiveSceneVO vo = new SensitiveSceneVO();
            BeanUtils.copyProperties(scene, vo);
            vo.setDevices(sceneIdDeviceMap.get(scene.getId()));
            resultVOs.add(vo);
        });
        jsonResult.setCode(JsonResultEnum.SUCCESS.getCode());
        jsonResult.setMsg(JsonResultEnum.SUCCESS.getMsg());
        jsonResult.setData(resultVOs);
        jsonResult.setTotal(resultVOs.size());
        return jsonResult;
    }


    /**
     * 获取厂房信息
     *
     * @return
     */
    @GetMapping("/getFactoryInfo")
    public JsonResult getFactoryInfo() {
        Date date = new Date();
        String start = DateUtils.getStartOfDay2(date);
        String end = DateUtils.getEndOfDay2(date);

        List<FactoryInfoVO> factoryInfoVOS = new ArrayList<>();

        // 查询当日工单数量（作业区域数量就是当日工单数量）
        for (int i = 1; i <= 2; i++) {
            FactoryInfoVO vo = new FactoryInfoVO();
            // 设置机组名称
            vo.setFactoryName(i + "#机组");
            List<Job> jobs = jobMapper.selectList(Wrappers.<Job>lambdaQuery().eq(Job::getUnitNum, i).between(Job::getStartTime, start, end));

            // 设置作业区域数量
            vo.setWorkRegionCount(jobs.size());

            // 设置作业人员数量
            if (!CollectionUtils.isEmpty(jobs)) {
                List<Long> jobIds = jobs.stream().map(Job::getJobId).collect(Collectors.toList());
                List<Integer> personnelIds = jobPersonnelMapper.selectPersonnelsByJobIds(jobIds);
                vo.setWorkPersonnelCount(personnelIds.size());
            }

            // 报警
            List<Scene> scenes = sceneService.selectSceneSByBuilding(i);
            List<AlarmReport> alarmReports = null;
            if (CollectionUtils.isEmpty(scenes)) {
                alarmReports = new ArrayList<>();
            } else {
                List<Device> devices = deviceService.selectBySceneIds(scenes.stream().map(Scene::getId).collect(Collectors.toList()));
                List<String> deviceIds = devices.stream().map(Device::getDeviceId).collect(Collectors.toList());
                // 这是视频报警，视频报警是ai报警
                alarmReports = alarmReportMapper.selectList(Wrappers.<AlarmReport>lambdaQuery()
                        .in(AlarmReport::getDeviceName, deviceIds)
                        .between(AlarmReport::getBeginTime, start, end));
            }

            // 围栏报警，围栏报警先根据机组号字段查围栏，然后根据围栏id查报警报表
            List<Path> paths = pathMapper.selectList(Wrappers.<Path>lambdaQuery().eq(Path::getBuilding, i));
            List<Integer> pathIds = paths.stream().map(Path::getPathId).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(pathIds)) {
                vo.setAlarmCount(alarmReports.size());
            } else {
                List<AlarmReport> pathAlarmReports = alarmReportMapper.selectList(Wrappers.<AlarmReport>lambdaQuery()
                        .in(AlarmReport::getPathId, pathIds)
                        .between(AlarmReport::getBeginTime, start, end));
                vo.setAlarmCount(alarmReports.size() + pathAlarmReports.size());
            }

            factoryInfoVOS.add(vo);
        }

        return JsonResult.success(factoryInfoVOS);

    }


    @GetMapping("/repairSceneBuilding")
    public JsonResult repairSceneBuilding() {
        List<Scene> allScene = sceneService.findAllScene();
//        List<Scene> allScene = new ArrayList<>();
//        Scene byId = sceneService.findById(1);
//        allScene.add(byId);

        for (Scene scene : allScene) {
            String scenePoint = scene.getScenePoint();
            JSONObject jsonObject = JSONObject.parseObject(scenePoint);
            jsonObject.putIfAbsent("building", 1);
            String s = jsonObject.toString();
            System.out.println(s);
            scene.setScenePoint(s);
            sceneService.update(scene);
        }

        return JsonResult.success();
    }

}
